﻿//--------------------------------------------------------------------------
// 
//  Copyright (c) Chili Software.  All rights reserved. 
// 
//  File: ExpressionsBag.cs
//
//  Description: Holds all expressions handled by LinqQuery<T>.
// 
//--------------------------------------------------------------------------

using System.Collections.Generic;
using System.Linq.Expressions;
using System;
using System.Linq;

namespace Chili.Opf3.Linq
{
	/// <summary>
	/// This class holds all expressions that are handled by a <see cref="LinqQuery{T}">LinqQuery</see>.
	/// </summary>
	internal sealed class ExpressionsBag : ICloneable
	{
		private List<Expression> _where = new List<Expression>();
		private List<OrderByExpression> _orderBy = new List<OrderByExpression>();
		private List<Expression> _groupJoin = new List<Expression>();
		private List<Expression> _join = new List<Expression>();

		/// <summary>
		/// Creates a new instance of the <see cref="ExpressionsBag">ExpressionsBag Class</see>.
		/// </summary>
		internal ExpressionsBag()
		{
		}

		/// <summary>
		/// Gets whether the bag is completely empty.
		/// </summary>
		/// <returns></returns>
		public bool IsEmpty()
		{
			return (_where.Count == 0 && _orderBy.Count == 0 && _groupJoin.Count == 0 && this.SelectMany == null
				&& _join.Count == 0 && this.Select == null);
		}

		/// <summary>
		/// Gets the group join expressions.
		/// </summary>
		public List<Expression> GroupJoin
		{
			get { return _groupJoin; }
		}

		/// <summary>
		/// Gets the order by expressions.
		/// </summary>
		public List<OrderByExpression> OrderBy
		{
			get { return _orderBy; }
		}

		/// <summary>
		/// Gets the where expresssions
		/// </summary>
		public List<Expression> Where
		{
			get { return _where; }
		}

		/// <summary>
		/// Gets and sets the select many expression.
		/// </summary>
		public Expression SelectMany { get; set; }
		
		/// <summary>
		/// Gets and sets the select expression.
		/// </summary>
		public Expression Select { get; set; }

		/// <summary>
		/// Gets and sets the top count that is returned by the query.
		/// </summary>
		public int TopCount { get; set; }

		/// <summary>
		/// Gets the join expressions.
		/// </summary>
		public List<Expression> Join 
		{
			get { return _join; }
		}

		#region ICloneable Members

		public object Clone()
		{
			ExpressionsBag clone = new ExpressionsBag();
			clone.GroupJoin.AddRange(this.GroupJoin);
			clone.Join.AddRange(this.Join);
			clone.OrderBy.AddRange(this.OrderBy);
			clone.Select = this.Select;
			clone.SelectMany = this.SelectMany;
			clone.TopCount = this.TopCount;
			clone.Where.AddRange(this.Where);

			return clone;
		}

		#endregion
	}
}
